<template>
  <div class="saturation" @mousedown.prevent.stop="selectSaturation">
    <canvas ref="canvasSaturationRef" />
    <div :style="attr.slideSaturationStyle" class="slide" />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from "vue"
import { createLinearGradient } from "./composible"
const props = defineProps({
  color: {
    type: String,
    default: "#000000",
  },
  hsv: {
    type: Object,
    default: null,
  },
  size: {
    type: Number,
    default: 152,
  },
})
const emit = defineEmits(["selectSaturation"])
const canvasSaturationRef=ref()
const attr = reactive({
  slideSaturationStyle: {},
})
onMounted(() => {
  renderColor()
  renderSlide()
})

const renderColor = () => {
  const canvas: any = canvasSaturationRef.value
  const size = props.size
  const ctx = canvas.getContext("2d")
  canvas.width = size
  canvas.height = size
  ctx.fillStyle = props.color
  ctx.fillRect(0, 0, size, size)
  createLinearGradient("l", ctx, size, size, "#FFFFFF", "rgba(255,255,255,0)")
  createLinearGradient("p", ctx, size, size, "rgba(0,0,0,0)", "#000000")
}
const renderSlide = () => {
  attr.slideSaturationStyle = {
    left: props.hsv.s * props.size - 5 + "px",
    top: (1 - props.hsv.v) * props.size - 5 + "px",
  }
}
const selectSaturation = (e: any) => {
  const { top: saturationTop, left: saturationLeft } = canvasSaturationRef.value.getBoundingClientRect()
  const ctx = e.target.getContext("2d")
  const mousemove = (e: any) => {
    let x = e.clientX - saturationLeft
    let y = e.clientY - saturationTop
    if (x < 0) {
      x = 0
    }
    if (y < 0) {
      y = 0
    }
    if (x > props.size) {
      x = props.size
    }
    if (y > props.size) {
      y = props.size
    }
    attr.slideSaturationStyle = {
      left: x - 5 + "px",
      top: y - 5 + "px",
    }
    const imgData = ctx.getImageData(Math.min(x, props.size - 1), Math.min(y, props.size - 1), 1, 1)
    const [r, g, b] = imgData.data
    emit("selectSaturation", { r, g, b })
  }
  mousemove(e)
  const mouseup = () => {
    document.removeEventListener("mousemove", mousemove)
    document.removeEventListener("mouseup", mouseup)
  }
  document.addEventListener("mousemove", mousemove)
  document.addEventListener("mouseup", mouseup)
}

defineExpose({renderColor,renderSlide})
</script>

<style lang="scss">
.saturation {
  position: relative;
  cursor: pointer;
  .slide {
    position: absolute;
    left: 100px;
    top: 0;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 1px solid #fff;
    box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.3);
    pointer-events: none;
  }
}
</style>
